package cn.mxz.robots.basic.remote;

import java.text.NumberFormat;

import net.sf.json.JSONObject;

import org.apache.log4j.Logger;

import cn.mxz.crawler_single.util.Encrypt;
import cn.mxz.rds.pojo.GaoKaoInfo;
import cn.mxz.rds.pojo.GaoKaoScore;
import cn.mxz.rds.pojo.User;
import cn.mxz.rds.service.GaoKaoRankService;
import cn.mxz.rds.service.UserService;
import cn.mxz.robots.basic.local.IStatus;
import cn.mxz.robots.pojo.Student;
import cn.mxz.robots.util.DeprecatedRedisGK;
import cn.mxz.robots.util.RankUtil;
import cn.mxz.robots.util.RobotsUtlis;

/**
 * 高考函数跳转
 * 
 * @author cuizhennan<cuizhennan@mouge.wang>
 * @since 2015-06-25
 */
public class GkForward
{
	private static Logger LOG = Logger.getLogger(GkForward.class);

	/**
	 * 模块控制器
	 */
	public static String forwardController(ExamControl examControl, String provinceId, String method, Student student, String captcha)
	{
		String result = "";
		// token
		String token = Encrypt.sha1(student.getIdCard() + "_gk");

		switch (method)
		{
		/* 获取验证码 */
		case "getCaptcha":
			result = examControl.reflectRobots(provinceId, student, method);
			break;
		/* 登录 */
		case "login":
			result = loginExecute(token, examControl, provinceId, method, student, captcha);
			break;
		/* 成绩查询 */
		case "score":
			result = findScore(provinceId, token);
			break;
		/* 成绩分析 */
		case "analysis":
			result = findAnalysis(examControl, provinceId, student, token);
			break;
		}

		return result;
	}

	/**
	 * 登录
	 * return string <code>JSONObject.toString()<code>
	 */
	private static String loginExecute(String token, ExamControl examControl, String provinceId, String method, Student student, String captcha)
	{
		try
		{
			if ("damage".equals(student.getStudentPwd()) && student.getStudentPwd() != null)
			{// 成绩登录
				JSONObject dataJson = new JSONObject();
				dataJson.put("result", IStatus.LOGIN_SUCCESS);
				dataJson.put("exam_id", "");
				dataJson.put("name", "");
				dataJson.put("ranking", "");
				dataJson.put("province", ProvinceFactory.provinceMap.get(provinceId).split("-")[1]);

				JSONObject score = new JSONObject();
				score.put("总分", student.getStudentId());

				dataJson.put("score", score.toString());

				new GkForward().new SaveThread(provinceId, student, dataJson.toString()).start();// 开启线程保存

				return dataJson.toString();
			}
			else
			{// 账号登录
				return loginToRobots(examControl, provinceId, method, student, captcha);
			}
		}
		catch (Exception e)
		{
			return "Method [loginExecute] Exception." + e.getMessage();
		}
	}

	/**
	 * 完好的学校的登录
	 */
	private static String loginToRobots(ExamControl examControl, String provinceId, String method, Student student, String captcha)
	{
		String result = examControl.reflectRobots(provinceId, student, method, captcha);

		String resultStatus = "";
		try
		{
			resultStatus = JSONObject.fromObject(result).getString("result");
		}
		catch (Exception e)
		{
			return "JSONObject Exception [loginToRobots]." + result;
		}

		if (resultStatus.contains(IStatus.LOGIN_SUCCESS))
		{
			new GkForward().new SaveThread(provinceId, student, result).start();// 开启线程保存
		}

		return result;
	}

	/**
	 * 成绩分析
	 */
	private static String findAnalysis(ExamControl examControl, String provinceId, Student student, String token)
	{
		String analys = "";
		try
		{
			String analysKeyData = "gk_analys_" + token;// 成绩分析key

			// DeprecatedRedisGK.del(analysKeyData);

			analys = DeprecatedRedisGK.hget(analysKeyData, "analysis");

			if ("".equals(analys) || analys == null)
			{
				analys = getAnalysDB(analysKeyData, provinceId, student, token);
			}
		}
		catch (Exception e)
		{
			LOG.error("findAnalysis Exception." + e.getMessage());
			return "findAnalysis Exception." + e.getMessage();
		}

		return analys;
	}

	/**
	 * 成绩分析 ==> 从数据库拿取今年排名对比去年排名分数
	 */
	private static String getAnalysDB(String anaylsKeyData, String provinceId, Student student, String token)
	{

		// 用token从数据库里取出个人信息
		String stuDataKey = "gk_stu_score_" + token;// 成绩key
		String score = DeprecatedRedisGK.hget(stuDataKey, "score");
		JSONObject dataJson = JSONObject.fromObject(score).getJSONObject("data");

		String rank = dataJson.getString("ranking");
		String type = student.getType().contains("w") ? "bw" : "bl";

		// 今年排名对比去年排名分数
		String lasterYearScore = "";
		// 击败同龄人的百分比
		String defeatPercent = "";
		try
		{
			lasterYearScore = String.valueOf(RankUtil.getTransformScore(Integer.parseInt(provinceId), Integer.parseInt(rank), type));

			// 计算百分比
			GaoKaoRankService gaoKaoRankService = new GaoKaoRankService();
			int defeat = gaoKaoRankService.getMaxRanking(Integer.parseInt(provinceId), type);
			NumberFormat numberFormat = NumberFormat.getInstance();
			numberFormat.setMaximumFractionDigits(0);
			defeatPercent = numberFormat.format((1 - (float) Integer.parseInt(rank) / (float) defeat) * 100);
		}
		catch (Exception e)
		{
			return "Method [getAnalysDB] Exception.";
		}

		JSONObject analys = new JSONObject();
		analys.put("name", dataJson.getString("name"));
		analys.put("rank", rank);
		analys.put("defeat_percent", defeatPercent);
		analys.put("yeared_rank_score", lasterYearScore);

		DeprecatedRedisGK.hset(anaylsKeyData, "analysis", analys.toString());

		return analys.toString();
	}

	/**
	 * 保存缓存
	 */
	private static void saveRedisCache(String provinceId, Student student, String result)
	{
		/* token */
		String mToken = Encrypt.sha1(student.getIdCard() + "_gk");

		LOG.info("provinceId:" + provinceId);
		LOG.info("mToken:" + mToken);
		LOG.info("result:" + result);

		/* 登录Studnet的Key */
		String stuloginKey = "gk_login_info_" + mToken;

		JSONObject loginInfo = new JSONObject();// 登录账号信息
		loginInfo.put("province_id", provinceId);
		loginInfo.put("student_id", student.getStudentId());
		loginInfo.put("student_pwd", student.getStudentPwd());
		loginInfo.put("id_card", student.getIdCard());
		loginInfo.put("account", student.getAccount());
		loginInfo.put("type", student.getType());

		// 保存账号信息
		DeprecatedRedisGK.set(stuloginKey, loginInfo.toString());

		/* 保存考生成绩信息,判读数据是否是JSON字符串 */
		if (RobotsUtlis.isElemetns(result, "(\\{.*\\})") && result.length() > 3)// {}或加空格
		{
			String stuDataKey = "gk_stu_score_" + mToken;
			DeprecatedRedisGK.hset(stuDataKey, "score", result);
		}
	}

	/**
	 * 保存数据到数据库
	 */
	private static void saveDB(String provinceId, Student student, String result)
	{
		try
		{
			JSONObject resultJson = JSONObject.fromObject(result).getJSONObject("data");

			// 用idCard从数据库里取出个人信息
			UserService service = new UserService();
			User user = service.find(student.getIdCard());// 查询是否存在User对象

			/* 如果数据库为空，则添加数据 */
			if (user == null || user.getGaoKaoInfo() == null)
			{
				// 保存info
				JSONObject info = new JSONObject();
				info.put("exam_id", resultJson.getString("exam_id"));
				info.put("name", resultJson.getString("name"));
				saveDBInfo(info.toString(), provinceId, student);
			}

			if (user == null || user.getGaoKaoScore() == null)
			{
				// 保存score
				JSONObject score = resultJson.getJSONObject("score");
				score.put("ranking", resultJson.get("ranking"));
				saveDBScore(score.toString(), provinceId, student);
			}
		}
		catch (Exception e)
		{
			LOG.error("Exception for class GkForward to [saveDB] method." + e.getMessage());
		}
	}

	/**
	 * 登录成功，保存的loginInfo和考生info信息
	 */
	private static void saveDBInfo(String info, String provinceId, Student student)
	{
		try
		{
			UserService userService = new UserService();
			User user = new User();
			user.setIdCard(student.getIdCard());// token 变为 idCard(身份证号)
			user.setRealname(JSONObject.fromObject(info).getString("name"));

			JSONObject gkInfoJson = JSONObject.fromObject(info);
			gkInfoJson.put("province_id", provinceId);
			gkInfoJson.put("student_id", student.getStudentId());
			gkInfoJson.put("student_pwd", student.getStudentPwd());
			gkInfoJson.put("id_card", student.getIdCard());
			gkInfoJson.put("account", student.getAccount());

			GaoKaoInfo gkInfo = new GaoKaoInfo();
			gkInfo.setGaokaoInfo(gkInfoJson.toString());// 保存考生信息

			user.setGaoKaoInfo(gkInfo);
			userService.save(user);
		}
		catch (Exception e)
		{
			LOG.error("Exception for class GkForward to [saveDBInfo] method." + e.getMessage());
		}
	}

	/**
	 * 保存Score到数据库
	 */
	private static void saveDBScore(String score, String provinceId, Student student)
	{
		try
		{
			UserService userService = new UserService();
			User user = userService.find(student.getIdCard());// 用身份证号更新User对象

			GaoKaoScore gkScore = new GaoKaoScore();
			gkScore.setScore(score);

			user.setGaoKaoScore(gkScore);

			userService.update(user);// 更新操作user的高考score

			GaoKaoScore gks = userService.find(student.getIdCard()).getGaoKaoScore();
			if (gks == null || (gks.getScore() == null || "".equals(gks.getScore())))
			{
				userService.update(user);
				LOG.warn("Waring method [saveDBScore],Update Failure.");
			}
		}
		catch (Exception e)
		{
			LOG.error("Exception for class GkForward to [saveDBScore] method." + e.getMessage());
		}
	}

	/**
	 * 从缓存查询成绩
	 */
	private static String findScore(String provinceId, String token)
	{
		// 用token从数据库里取出个人信息
		String stuDataKey = "gk_stu_score_" + token;
		String data = DeprecatedRedisGK.hget(stuDataKey, "score");

		if (data == null || "".equals(data))
		{
			return "error_token";// 缓存信息不存在，请重新登录
		}

		if (!RobotsUtlis.isElemetns(data, "(\\{.*\\})"))
		{
			return "Json data Exception for method [findScore]\n." + data;
		}

		return data;
	}

	/* 保存信息到数据库和缓存 */
	private class SaveThread extends Thread
	{
		private String mProvinceId;
		private Student mStudent;
		private String mResult;

		public SaveThread(String provinceId, Student student, String result)
		{
			this.mProvinceId = provinceId;
			this.mStudent = student;
			this.mResult = result;
		}

		@Override
		public void run()
		{
			try
			{
				// 保存数据库
				saveDB(mProvinceId, mStudent, mResult);
				// 设置缓存
				saveRedisCache(mProvinceId, mStudent, mResult);
			}
			catch (Exception e)
			{
				LOG.error("Exception SaveThread." + e.getMessage());
			}
		}
	}
}
